package com.tbit.uqbike.client.util.aliyun;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import com.tbit.uqbike.client.pojo.OssConfig;
import com.tbit.uqbike.client.util.FaceUtil;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.List;


/**
 * @Author: chen
 * @Description:
 * @Date: 创建于 10:50 2020/8/3
 */
@Slf4j
public class OssFileUtils {

    public static Integer IMAGE = 2;

    public static Integer MP3 = 1;

    /**
     * @Description:
     * @Param: [inputStream, oosConfig, fileName, contentType, isMuisc(1代表map文件，2代表image 999-本地人脸识别-就为了不压缩文件而已)]
     * @return: java.lang.String
     * @Author: Jing
     * @Date: 2021/5/24
     */
    public static String uploadByAliYun(InputStream inputStream, OssConfig oosConfig, String fileName, String contentType, int isMuisc) throws Exception {
        /**判断文件大小*/
        //开始压缩图片
        if (isMuisc == 2) {
            inputStream = compress(inputStream);
        }
        //上传到阿里云
        OSSClient ossClient = new OSSClient(oosConfig.getEndpoint(), oosConfig.getAccessKeyId(), oosConfig.getAccessKeySecret());

        PutObjectRequest putObjectRequest = new PutObjectRequest(oosConfig.getBucketName(), fileName, inputStream);
        putObjectRequest.setMetadata(init(inputStream, fileName, contentType));
        // 上传文件。
        ossClient.putObject(putObjectRequest);
        //ossClient.putObject(oosConfig.getBucketName(), fileName, instream,objectMetadata);
        ossClient.shutdown();
        return "https://" + oosConfig.getBucketName() + "." + oosConfig.getEndpoint() + "/" + fileName;
    }

    public static InputStream base64Toio(String imgStr) {
        String encodedImg = imgStr;
        byte[] decodedImg = Base64.getDecoder().decode(encodedImg.getBytes(StandardCharsets.UTF_8));
        // 签名图片的二进制流
        InputStream inputStream = new ByteArrayInputStream(decodedImg);
        return inputStream;
    }

    public static ObjectMetadata init(InputStream inputStream, String fileName, String contentType) throws IOException {
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentLength(inputStream.available());
        objectMetadata.setCacheControl("no-cache");
        objectMetadata.setHeader("Pragma", "no-cache");
        objectMetadata.setContentType(getcontentType(contentType));
        objectMetadata.setContentDisposition("inline;filename=" + fileName);

        // 指定上传文件操作时是否覆盖同名Object。
        // 不指定x-oss-forbid-overwrite时，默认覆盖同名Object。
        // 指定x-oss-forbid-overwrite为false时，表示允许覆盖同名Object。
        // 指定x-oss-forbid-overwrite为true时，表示禁止覆盖同名Object，如果同名Object已存在，程序将报错。
        objectMetadata.setHeader("x-oss-forbid-overwrite", "false");
        return objectMetadata;
    }


    /**
     * Description: 判断OSS服务文件上传时文件的contentType
     *
     * @param FilenameExtension 文件后缀
     * @return String
     */
    public static String getcontentType(String FilenameExtension) {
        if ("bmp".equalsIgnoreCase(FilenameExtension)) {
            return "image/bmp";
        }
        if ("gif".equalsIgnoreCase(FilenameExtension)) {
            return "image/gif";
        }
        if ("jpeg".equalsIgnoreCase(FilenameExtension) ||
                "jpg".equalsIgnoreCase(FilenameExtension)
        ) {
            return "image/jpeg";
        }
        if ("png".equalsIgnoreCase(FilenameExtension)) {
            return "image/png";
        }
        if ("html".equalsIgnoreCase(FilenameExtension)) {
            return "text/html";
        }
        if ("txt".equalsIgnoreCase(FilenameExtension)) {
            return "text/plain";
        }
        if ("vsd".equalsIgnoreCase(FilenameExtension)) {
            return "application/vnd.visio";
        }
        if ("pptx".equalsIgnoreCase(FilenameExtension) ||
                "ppt".equalsIgnoreCase(FilenameExtension)) {
            return "application/vnd.ms-powerpoint";
        }
        if ("docx".equalsIgnoreCase(FilenameExtension) ||
                "doc".equalsIgnoreCase(FilenameExtension)) {
            return "application/msword";
        }
        if ("xml".equalsIgnoreCase(FilenameExtension)) {
            return "text/xml";
        }
        if ("mp3".equalsIgnoreCase(FilenameExtension)) {
            return "audio/mp3";
        }
        if ("mp4".equalsIgnoreCase(FilenameExtension)) {
            return "video/mpeg4";
        }
        if ("wav".equalsIgnoreCase(FilenameExtension)) {
            return "audio/wav";
        }
        return "image/jpeg";
    }


    /**
     * 压缩图片(没有原图)
     * 默认输出25%质量图片
     *
     * @param
     * @return
     * @throws IOException
     */
    public static InputStream compress(InputStream in) throws Exception {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        Thumbnails.of(in).scale(1f).outputQuality(0.25f).toOutputStream(os);
        InputStream is = new ByteArrayInputStream(os.toByteArray());
        in.close();
        os.close();
        return is;
    }


    /**
     * 下载oss文件
     *
     * @param oosConfig 配置信息
     * @param fileName  文件名称
     * @param pathName  下载到本地路径
     */
    public static void upload(OssConfig oosConfig, String fileName, String pathName) {
        if (fileName.contains(".com")) {
            fileName = fileName.substring(fileName.lastIndexOf("/") + 1);
        }
        // 创建OSSClient实例。
        OSS ossClient = new OSSClient(oosConfig.getEndpoint(), oosConfig.getAccessKeyId(), oosConfig.getAccessKeySecret());
        try {
            // 下载Object到本地文件，并保存到指定的本地路径中。如果指定的本地文件存在会覆盖，不存在则新建。
            // 如果未指定本地路径，则下载后的文件默认保存到示例程序所属项目对应本地路径中。
            ossClient.getObject(new GetObjectRequest(oosConfig.getBucketName(), fileName), new File(pathName));
        } catch (OSSException oe) {
            log.error("Error Code:" + oe.getErrorCode());
        } catch (ClientException ce) {
            log.error("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }

    }

    /**
     * oss删除文件
     *
     * @param oosConfig oss的配置
     * @param fileName  文件名
     */
    public static void deleteObject(OssConfig oosConfig, String fileName) {
        OSS ossClient = new OSSClient(oosConfig.getEndpoint(), oosConfig.getAccessKeyId(), oosConfig.getAccessKeySecret());
        try {
            ossClient.deleteObject(oosConfig.getBucketName(), fileName);
        } catch (OSSException oe) {
            log.error("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            log.error("Error Message:" + oe.getErrorMessage());
            log.error("Error Code:" + oe.getErrorCode());
            log.error("Request ID:" + oe.getRequestId());
            log.error("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            log.error("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            log.error("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

}
